
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class HotSwapManager {

    private final Map<String, HotSwapClassLoader> classLoaders = new ConcurrentHashMap<>();
    private final String baseClassDir = "hotswap_classes";

    // 注册类加载器
    public void registerClassLoader(String moduleName, String classPath) {
        HotSwapClassLoader classLoader = new HotSwapClassLoader(classPath);
        classLoaders.put(moduleName, classLoader);
    }

    // 热更新单个类
    public HotSwapResult hotSwapClass(String moduleName, String className) {
        HotSwapClassLoader classLoader = classLoaders.get(moduleName);
        if (classLoader == null) {
            return new HotSwapResult(false, "ClassLoader not found for module: " + moduleName);
        }

        boolean success = classLoader.hotSwapClass(className);
        if (success) {
            return new HotSwapResult(true, "Class hot-swapped successfully: " + className);
        } else {
            return new HotSwapResult(false, "Failed to hot-swap class: " + className);
        }
    }

    // 热更新整个模块
    public HotSwapResult hotSwapModule(String moduleName) {
        HotSwapClassLoader classLoader = classLoaders.get(moduleName);
        if (classLoader == null) {
            return new HotSwapResult(false, "ClassLoader not found for module: " + moduleName);
        }

        Set<String> classes = classLoader.getLoadedClasses();
        List<String> results = new ArrayList<>();
        boolean allSuccess = true;

        for (String className : classes) {
            boolean success = classLoader.hotSwapClass(className);
            results.add(className + ": " + (success ? "SUCCESS" : "FAILED"));
            if (!success) {
                allSuccess = false;
            }
        }

        return new HotSwapResult(allSuccess, String.join("\n", results));
    }

    // 回滚类
    public HotSwapResult rollbackClass(String moduleName, String className) {
        HotSwapClassLoader classLoader = classLoaders.get(moduleName);
        if (classLoader == null) {
            return new HotSwapResult(false, "ClassLoader not found for module: " + moduleName);
        }

        boolean success = classLoader.rollbackClass(className);
        if (success) {
            return new HotSwapResult(true, "Class rolled back successfully: " + className);
        } else {
            return new HotSwapResult(false, "No backup found for class: " + className);
        }
    }

    // 上传类文件
    public HotSwapResult uploadClassFile(String moduleName, String className, byte[] classData) {
        try {
            String classPath = baseClassDir + File.separator + moduleName;
            File dir = new File(classPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            String filePath = className.replace('.', File.separatorChar) + ".class";
            File classFile = new File(classPath, filePath);

            // 确保目录存在
            classFile.getParentFile().mkdirs();

            // 写入文件
            java.nio.file.Files.write(classFile.toPath(), classData);

            return new HotSwapResult(true, "Class file uploaded successfully: " + className);
        } catch (Exception e) {
            return new HotSwapResult(false, "Failed to upload class file: " + e.getMessage());
        }
    }

    // 获取已加载的类列表
    public Map<String, Set<String>> getLoadedClasses() {
        Map<String, Set<String>> result = new HashMap<>();
        for (Map.Entry<String, HotSwapClassLoader> entry : classLoaders.entrySet()) {
            result.put(entry.getKey(), entry.getValue().getLoadedClasses());
        }
        return result;
    }

    // 清理内存
    public void cleanup() {
        for (HotSwapClassLoader loader : classLoaders.values()) {
            loader.cleanupBackups();
        }
    }

    public static class HotSwapResult {
        private boolean success;
        private String message;
        private Date timestamp;

        public HotSwapResult(boolean success, String message) {
            this.success = success;
            this.message = message;
            this.timestamp = new Date();
        }

        // getters and setters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public Date getTimestamp() { return timestamp; }
    }
}